
namespace ShoppingCart.DataAccess
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using Business.Entity;
    using Microsoft.Practices.EnterpriseLibrary.Data;

	/// <summary>
	/// Represents the DataAccess of EnvioData.
	/// </summary>
	public class EnvioData : Singleton<EnvioData>
	{
		#region Attributes

		private readonly Database BaseDatos = DatabaseFactory.CreateDatabase();

		#endregion

		#region Methods

		/// <summary>
		/// Selects all records from the Envio table by a foreign key.
		/// </summary>
		public Envio Obtener(int idPedido)
		{
			var envio = default(Envio);
			var comando = BaseDatos.GetStoredProcCommand("SelectEnvio");

			BaseDatos.AddInParameter(comando, "IdPedido", DbType.Int32, idPedido);

			using (var lector = BaseDatos.ExecuteReader(comando))
			{
				while (lector.Read())
				{
                    envio = new Envio
                    {
                        Pedido = new Pedido { IdPedido = idPedido },
                        Costo = lector.GetDecimal(lector.GetOrdinal("Costo")),
                        FechaEnvio = lector.IsDBNull(lector.GetOrdinal("FechaEnvio")) ? (DateTime?)null : lector.GetDateTime(lector.GetOrdinal("FechaEnvio")),
                        Distrito = DistritoData.Instancia.Obtener(lector.GetInt32(lector.GetOrdinal("IdDistrito"))),
                        Direccion = lector.GetString(lector.GetOrdinal("Direccion")),
                        Comentario = lector.IsDBNull(lector.GetOrdinal("Comentario")) ? default(string) : lector.GetString(lector.GetOrdinal("Comentario")),
                        Estado = lector.GetByte(lector.GetOrdinal("Estado"))
                    };
				}
			}
			comando.Dispose();
			return envio;
		}

		/// <summary>
		/// Saves a record to the Envio table.
		/// </summary>
		public int Agregar(Envio envio)
		{
			var comando = BaseDatos.GetStoredProcCommand("InsertEnvio");
			BaseDatos.AddInParameter(comando, "IdPedido", DbType.Int32, envio.Pedido.IdPedido);
			BaseDatos.AddInParameter(comando, "Costo", DbType.Currency, envio.Costo);
			BaseDatos.AddInParameter(comando, "FechaEnvio", DbType.DateTime, envio.FechaEnvio);
			BaseDatos.AddInParameter(comando, "IdDistrito", DbType.Int32, envio.Distrito.IdDistrito);
			BaseDatos.AddInParameter(comando, "Direccion", DbType.String, envio.Direccion);
			BaseDatos.AddInParameter(comando, "Comentario", DbType.String, envio.Comentario);
			BaseDatos.AddInParameter(comando, "Estado", DbType.Byte, envio.Estado);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Agregar Envio.");
			comando.Dispose();
			return 1;
		}

		/// <summary>
		/// Updates a record in the Envio table.
		/// </summary>
		public bool Modificar(Envio envio)
		{
			var comando = BaseDatos.GetStoredProcCommand("UpdateEnvio");
			BaseDatos.AddInParameter(comando, "IdPedido", DbType.Int32, envio.Pedido.IdPedido);
			BaseDatos.AddInParameter(comando, "Costo", DbType.Currency, envio.Costo);
			BaseDatos.AddInParameter(comando, "FechaEnvio", DbType.DateTime, envio.FechaEnvio);
			BaseDatos.AddInParameter(comando, "IdDistrito", DbType.Int32, envio.Distrito.IdDistrito);
			BaseDatos.AddInParameter(comando, "Direccion", DbType.String, envio.Direccion);
			BaseDatos.AddInParameter(comando, "Comentario", DbType.String, envio.Comentario);
			BaseDatos.AddInParameter(comando, "Estado", DbType.Byte, envio.Estado);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Modificar Envio.");

			comando.Dispose();
			return true;
		}

		/// <summary>
		/// Deletes a record from the Envio table by its primary key.
		/// </summary>
		public bool Eliminar(int idPedido)
		{
			var comando = BaseDatos.GetStoredProcCommand("DeleteEnvio");
			BaseDatos.AddInParameter(comando, "IdPedido", DbType.Int32, idPedido);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Eliminar Envio.");
			comando.Dispose();
			return true;
		}

		/// <summary>
		/// Selects all records from the Envio table by a foreign key.
		/// </summary>
		public IList<Envio> ListarPorIdPedido(int idPedido)
		{
			var entidades = new List<Envio>();
			var comando = BaseDatos.GetStoredProcCommand("SelectEnvioByIdPedido");

			BaseDatos.AddInParameter(comando, "IdPedido", DbType.Int32, idPedido);

			using (var lector = BaseDatos.ExecuteReader(comando))
			{
				while (lector.Read())
				{
                    entidades.Add(new Envio
                    {
                        Pedido = PedidoData.Instancia.Obtener(lector.GetInt32(lector.GetOrdinal("IdPedido"))),
                        Costo = lector.GetDecimal(lector.GetOrdinal("Costo")),
                        FechaEnvio = lector.IsDBNull(lector.GetOrdinal("FechaEnvio")) ? (DateTime?)null : lector.GetDateTime(lector.GetOrdinal("FechaEnvio")),
                        Distrito = DistritoData.Instancia.Obtener(lector.GetInt32(lector.GetOrdinal("IdDistrito"))),
                        Direccion = lector.GetString(lector.GetOrdinal("Direccion")),
                        Comentario = lector.IsDBNull(lector.GetOrdinal("Comentario")) ? default(string) : lector.GetString(lector.GetOrdinal("Comentario")),
                        Estado = lector.GetByte(lector.GetOrdinal("Estado"))
                    });
				}
			}
			comando.Dispose();
			return entidades;
		}

		#endregion
	}
}
